package com.smile.mybatis;

import java.io.*;
import java.nio.file.*;
import java.util.regex.*;
import java.util.List;
import java.util.ArrayList;

public class SQLFileProcessor {


    public static void main(String[] args) {
        try {
            // 处理指定SQL文件
            SQLFileProcessor.processSQLFile("C:\\Users\\14002\\Desktop\\约束.txt");
            System.out.println("SQL文件处理完成！");
        } catch (IOException e) {
            System.err.println("处理SQL文件时出错: " + e.getMessage());
        }
    }

    /**
     * 修正SQL文件中的DO块
     * @param filePath SQL文件路径
     */
    public static void processSQLFile(String filePath) throws IOException {
        List<String> lines = Files.readAllLines(Paths.get(filePath));
        List<String> processedLines = new ArrayList<>();

        for (int i = 0; i < lines.size(); i++) {
            String line = lines.get(i);

            // 检测DO块开始
            if (line.trim().startsWith("DO $$") && hasAlterTableInBlock(lines, i)) {
                // 生成修正后的DO块
                List<String> fixedBlock = createFixedDOBlock(lines, i);
                processedLines.addAll(fixedBlock);

                // 跳过原DO块
                i = skipToBlockEnd(lines, i);
            } else {
                processedLines.add(line);
            }
        }

        // 写回文件
        Files.write(Paths.get(filePath), processedLines);
    }

    /**
     * 检查DO块中是否包含ALTER TABLE语句
     */
    private static boolean hasAlterTableInBlock(List<String> lines, int startIndex) {
        for (int i = startIndex; i < Math.min(startIndex + 20, lines.size()); i++) {
            if (lines.get(i).contains("ALTER TABLE") && lines.get(i).contains("ALTER COLUMN")) {
                return true;
            }
            if (lines.get(i).trim().equals("END $$;")) {
                break;
            }
        }
        return false;
    }

    /**
     * 创建修正后的DO块
     */
    private static List<String> createFixedDOBlock(List<String> lines, int startIndex) {
        // 提取ALTER TABLE信息
        String[] tableInfo = extractTableColumnInfo(lines, startIndex);

        if (tableInfo != null) {
            String schema = tableInfo[0];
            String tableName = tableInfo[1];
            String columnName = tableInfo[2];

            List<String> block = new ArrayList<>();
            block.add("DO $$");
            block.add("BEGIN");
            block.add("    IF EXISTS (");
            block.add("        SELECT 1 FROM information_schema.tables ");
            block.add("        WHERE table_name = '" + tableName + "'");
            block.add("        AND table_schema = '" + schema + "'");
            block.add("    ) AND EXISTS (");
            block.add("        SELECT 1 FROM information_schema.columns ");
            block.add("        WHERE table_name = '" + tableName + "' ");
            block.add("        AND column_name = '" + columnName + "'");
            block.add("        AND table_schema = '" + schema + "'");
            block.add("    ) THEN");
            block.add("        ALTER TABLE \"" + schema + "\".\"" + tableName + "\" ");
            block.add("        ALTER COLUMN \"" + columnName + "\" SET DEFAULT 0;");
            block.add("    END IF;");
            block.add("END $$;");

            return block;
        }

        // 如果无法提取信息，返回原块
        return extractOriginalBlock(lines, startIndex);
    }

    /**
     * 提取表和列信息
     */
    private static String[] extractTableColumnInfo(List<String> lines, int startIndex) {
        Pattern pattern = Pattern.compile(
                "ALTER TABLE \"([^\"]+)\"\\.\"([^\"]+)\"\\s+ALTER COLUMN \"([^\"]+)\"");

        for (int i = startIndex; i < Math.min(startIndex + 20, lines.size()); i++) {
            Matcher matcher = pattern.matcher(lines.get(i));
            if (matcher.find()) {
                return new String[]{matcher.group(1), matcher.group(2), matcher.group(3)};
            }
            if (lines.get(i).trim().equals("END $$;")) {
                break;
            }
        }
        return null;
    }

    /**
     * 提取原始DO块
     */
    private static List<String> extractOriginalBlock(List<String> lines, int startIndex) {
        List<String> block = new ArrayList<>();
        for (int i = startIndex; i < lines.size(); i++) {
            block.add(lines.get(i));
            if (lines.get(i).trim().equals("END $$;")) {
                break;
            }
        }
        return block;
    }

    /**
     * 跳转到DO块结束位置
     */
    private static int skipToBlockEnd(List<String> lines, int startIndex) {
        for (int i = startIndex; i < lines.size(); i++) {
            if (lines.get(i).trim().equals("END $$;")) {
                return i;
            }
        }
        return startIndex;
    }
}
